#include <iostream>
#include <cstdlib> 
#include <limits>
#include <math.h>

#include "Image.H"
#include "IO.H"
#include "Util.H"

#include "filter.h"

using namespace pip;
using namespace std;


int main(int argc, char *argv[])
{
  Stopwatch time;
  time.start();
  string programname = argv[0];//look for commandline arguments: program name
  string fileEnding  = "";  //i solved the exercise before the hint with the 'getVectorArg'
  string ag1		 = "";  // but i already tested this version and therefore want to keep it
  string ag2		 = "";
  string ag3		 = "";
  bool isImage		 = false;  // an picture is passed as agument?
  bool isKernel		 = false;  // a kernel is passed as argument?
  if(argc >=3)             
  {								//at least three arguments needed
	  ag1        = argv[1];     
	  ag2        = argv[2];
	  ag3        = argv[3];
	  if(ag1.size() >= 5) 
		  fileEnding = ag1.substr(ag1.size() - 4,ag1.size()).c_str(); // image-file-ending
	  if(strcmp(ag2.c_str(),"-kernel") == 0)   //keyword kernel?
		  isKernel = true;
	  if(    0== strcmp( fileEnding.c_str(),".pip")  // is the image a pip or bmp?
		  || 0== strcmp( fileEnding.c_str(),".bmp")
		  || 0== strcmp( fileEnding.c_str(),".BMP")
		  || 0== strcmp( fileEnding.c_str(),".PIP"))
		  isImage = true;
  }
  if ( isImage                // ARGUMENTS SEEM TO BE OKAY
	  && isKernel)
  {
	vector<float> kernel_line;	  //for the values of the kernel 
	float vec=0;				  //current value
	bool isfloat = false;         // to remember if string contained point or komma
	string tmp = "";
	ag3 = " 0.04 0.04 0.04 0.04 0.04 0.04 0.04 0.04 0.04 0.04 0.04 0.04 0.04 0.04 0.04 0.04 0.04 0.04 0.04 0.04 0.04 0.04 0.04 0.04 0.04";
	ag1 = "trees.bmp";
	ag3.append(" ");//to ensure no number stays unencoded we need a ending space
	for(int i = 0 ; i < (signed int)ag3.size();++i) //for all chars in the kernel argument
	{
		if(int(ag3[i])!=32 )//if not space (ascii)
		{
			tmp.push_back(ag3[i]);  //collect chars till next space
			if(    int(ag3[i])==44  //remember when its a floating value
				|| int(ag3[i])==46)
				isfloat = true;
		}
		else if(strcmp(tmp.c_str(),"")!=0) //else if chars were collected
		{
			if(isfloat)	vec = float(atof(tmp.c_str()));  //convert char to value
			else		vec = float(atoi(tmp.c_str()));
			kernel_line.push_back(float(vec));           // but value into vector
			tmp="";                 //reset current values
			vec=0;
			isfloat = false;
		}
	}

	int kernel_size = int(sqrt(float(kernel_line.size()))); //assume NxN lernel and calculate N
	int kx=0;                                 
	int ky=0;
	Image<float> kernel(Dimension(kernel_size,kernel_size)); //store kernel in picture
	for(int j = 0 ; j < kernel_size*kernel_size; ++j)  //for all kernel values
	{
		ky=j%kernel_size;		//div and mod for instead of nested loops
		kx=j/kernel_size;
		kernel(kx,ky) = kernel_line[j];         // get vector into NxN shape
	}
	cout <<"KERNEL:\n " ;     //display the resulting kernel 
	for(int x = 0 ; x < kernel_size; ++x)
	{
		for(int y = 0 ; y < kernel_size; ++y)
		{
			cerr<<kernel(x,y)<<" ";
		}
		cerr <<endl;
	}
	float min=0;
	float max=0;
  Image<float> picture;   // load the given image
  loadimage(ag1,picture);
  getMinMaxImage(picture,min,max); //display its extrema
  cout << "\n minimum input: "
	  << min 
	  << "\n maximum input: " 
	  << max 
	  <<endl;
  Image<float> out(Dimension(picture.dim(0),picture.dim(1))); //get an output image
  Stopwatch time2;
  time2.start();
  filter(picture,out,kernel);        // convolve mask with input-image
  cout << " Time of filter alone: " 
	   << time2.stop()
	   << endl;
  getMinMaxImage(out,min,max);    
  cout << "\n minimum output: "  //display new extrema
	  << min 
	  << "\n maximum output:  " 
	  << max 
	  <<endl;
  saveimage("result2.bmp",out);     //save the image into image-name
  cout << "Processing time: " 
	  << time.stop()               // stop time
	  << " s"
	  <<endl;
  cout << g0(1, 2.0) <<endl;
  cout << g1(1, 2.0) <<endl;

  system("pause");

  }
  else
  {
	  cout <<  "No arguments was supplied. "
		 << "\n Usage: "
	     << "\n " 
		 << programname
		 << " IMAGE.{bmp,pip} -kernel \" KERNEL \" \n"
		 << "    where the kernel may contain floats or integers. assumed shape is square."
		 << "\n Example:\n   janpeter.bmp -kernel \"-1 -1 -1 0 0 0 1 1 1\"\n\n ";
	   system("pause");
	   return 2;//arguments did not fit requirements
  }
  return -5; //never end here?
}